import React, { PureComponent } from 'react'
import {
  Row, Col, Dropdown, Menu,
} from 'antd'
import PropTypes from 'prop-types'
import styles from './index.less'

/**
 * 使用 ProTableOperate 组件时，需与 OperateItem 静态方法配合使用，示例 <OperateItem>element node</OperateItem>
 * ProTableOperate 可传入的参数有：
 *  1、toggleOperate：是否隐藏 收起/展开 按钮 (如果设为隐藏按钮，handleToggleSta设置属性值不生效) 超过三个元素，toggleOperate 默认值为true，反之为false
 *  2、unfolded 默认为展开状态，值为 true
 *  3、notItemPadding 阻止OperateItem带间距，值为 false
 * OperateItem 可传入的参数有：
 *  1、itemType 如果传入的是按钮，则传入 itemType 为 'btn' 的值，其余情况无需设置itemType属性
 *  2、foldNum 设置按钮Item里超过多少个按钮开始折叠，默认值为 3
 *  3、align 设置 OperateItem 里元素的对齐方式，默认值为'right'，可设置值为 'left'、'center'、'right'
 *  4、fill  是否填充整个栅格，只对 OperateItem 传入一个元素的时候生效
 *  5、large_label 设置更大长度的label
 *  6、customFlex 自定义使用flex模式布局元素
 * */

export default class ProTableOperate extends PureComponent {
  static defaultProps = {
    unfolded: true,
    children: null,
    notItemPadding: false,
    className: {},
    style: {},
  }

  static propTypes = {
    // eslint-disable-next-line react/require-default-props
    toggleOperate: PropTypes.bool,
    // eslint-disable-next-line react/no-unused-prop-types
    notItemPadding: PropTypes.bool,
    unfolded: PropTypes.bool,
    children: PropTypes.node,
    // eslint-disable-next-line react/no-unused-prop-types
    className: PropTypes.oneOfType([
      PropTypes.object,
      PropTypes.string,
    ]),
    // eslint-disable-next-line react/no-unused-prop-types
    style: PropTypes.object,
  }

  static OperateItem(props = {}) {
    const {
      children: childrenParams,
      itemType,
      toggleOperate,
      unfoldedSta,
      handleToggleOperate,
      className,
      customFlex = false,
      foldNum = 3,
      align = 'right',
      fill = false,
      large_label,
    } = props

    // 过滤掉为null的btn, children 如果只传入一个元素，其类型为object
    const children = childrenParams?.length
      ? childrenParams?.filter((item) => item !== null && item !== undefined)
      : childrenParams

    const resElement = (
      Array.isArray(children) ? (
        <>
          <span
            className={`${styles.label} ${fill ? styles.label_fill : ''} ${large_label ? styles.large_label : ''}`}
          >{children[0]}</span>
          <span
            className={`${styles.cont} ${fill ? styles.cont_fill : ''} ${large_label ? styles.large_cont : ''}`}
          >{children.slice(1)}</span>
        </>
      ) : (
        <span className={`${fill ? `${styles.cont} ${styles.fill}` : styles.cont}`}>{children}</span>
      )
    )

    return (
      customFlex
        ? <div className={`${styles.operate_item_flex} ${className}`} style={{ justifyContent: align }}>
          {
            itemType === 'btn' ? (
              <span className={styles.btn_wrap} style={{ textAlign: align }}>
                {
                Array.isArray(children) ? children?.slice(0, foldNum) : children
              }
                {children?.length > foldNum && (
                  <Dropdown
                    placement="bottom"
                    getPopupContainer={(triggerNode) => triggerNode.parentNode}
                    overlayClassName={styles.dropdown_sty}
                    overlay={
                      <Menu>
                        {children?.slice(foldNum)?.map((item, index) => (
                          <Menu.Item key={index}>
                            {item}
                          </Menu.Item>
                        ))}
                      </Menu>
                    }
                  >
                    <i className="iconfont icon-more" />
                  </Dropdown>
                )}
                {
                  toggleOperate && (
                    <div className={styles.toggle_btn} onClick={handleToggleOperate}>
                      {
                        unfoldedSta ? (
                          <>
                            收起 <i className="iconfont icon-shang" />
                          </>
                        ) : (
                          <>
                            展开 <i className="iconfont icon-xia" />
                          </>
                        )
                      }
                    </div>
                  )
                }
              </span>
            ) : resElement
          }
        </div> : <div className={`${styles.operate_item} ${className}`} style={{ textAlign: align }}>
          {
            itemType === 'btn' ? (
              <span className={styles.btn_wrap} style={{ textAlign: align }}>
                {
                  Array.isArray(children) ? children?.slice(0, foldNum) : children
                }
                {children?.length > foldNum && (
                  <Dropdown
                    placement="bottom"
                    getPopupContainer={(triggerNode) => triggerNode.parentNode}
                    overlayClassName={styles.dropdown_sty}
                    overlay={
                      <Menu>
                        {children?.slice(foldNum)?.map((item, index) => (
                          <Menu.Item key={index}>
                            {item}
                          </Menu.Item>
                        ))}
                      </Menu>
                    }
                  >
                    <i className="iconfont icon-more" />
                  </Dropdown>
                )}
                {
                  toggleOperate && (
                    <div className={styles.toggle_btn} onClick={handleToggleOperate}>
                      {
                        unfoldedSta ? (
                          <>
                            收起 <i className="iconfont icon-shang" />
                          </>
                        ) : (
                          <>
                            展开 <i className="iconfont icon-xia" />
                          </>
                        )
                      }
                    </div>
                  )
                }
              </span>
            ) : resElement
          }
        </div>
    )
  }

  // eslint-disable-next-line react/sort-comp
  toggleOperateDefault = () => {
    const { children, toggleOperate = children?.length > 3 } = this.props
    return toggleOperate
  }

  state = {
    unfoldedSta: !this.toggleOperateDefault() ? true : this.props.unfolded,
  }

  handleToggleOperate = () => {
    this.setState((prevState) => ({
      unfoldedSta: !prevState.unfoldedSta,
    }))
  }

  showChildren = (children, unfoldedSta) => {
    if (unfoldedSta || !children || children.length <= 3) {
      return children
    }
    return (
      [...children.slice(0, 2), ...children.slice(children.length - 1, children.length)]
    )
  }

  render() {
    const {
      children, notItemPadding, toggleOperate = children?.length > 3, className, style, itemSpan = 8,
    } = this.props || {}
    const { unfoldedSta } = this.state
    const childrenCopy = []

    React.Children.map(children, (child) => {
      if (child?.props?.itemType === 'btn') {
        const copyChild = React.cloneElement(child, {
          toggleOperate,
          unfoldedSta,
          handleToggleOperate: this.handleToggleOperate,
        })
        childrenCopy.push(copyChild)
      } else {
        childrenCopy.push(child)
      }
    })

    const showChildren = this.showChildren(childrenCopy, unfoldedSta)
    const childrenLen = showChildren.length

    if (showChildren[childrenLen - 1]?.props?.itemType === 'btn' && childrenLen % 3 !== 0) {
      const modulo = 3 - (childrenLen % 3)
      const seatArray = new Array(modulo)
      showChildren.splice(childrenLen - 1, 0, ...seatArray)
    }
    return (
      <Row className={`${styles.table_bar} ${className}`} style={style}>
        {
          showChildren.map((item, index) => (
            <Col
              className={`${styles.item_col} ${notItemPadding ? styles.item_col_no_padding : ''}`}
              key={index.toString()}
              span={item?.props?.theItemSpan || itemSpan}
            >{item}</Col>
          ))
        }
      </Row>
    )
  }
}
